package canss.webservice.service;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Hashtable;
import java.util.LinkedList;

import javax.jws.*;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.beehive.controls.api.bean.Control;
import org.xml.sax.SAXException;

import weblogic.jdbc.SQLExceptionWrapper;

import canss.encoder.DBStringEncoder;
import canss.supports.basic;
import canss.webservice.controls.ChannelControl;
import canss.webservice.controls.ContentControl;
import canss.webservice.controls.ContentDescControl;
import canss.webservice.controls.ContentsChannelHoldsControl;
import canss.webservice.controls.EventDescriptionControl;
import canss.webservice.controls.PersonControl;
import canss.webservice.model.Channel;
import canss.webservice.model.ContentDesc;
import canss.webservice.model.ContentsChannelHolds;
import canss.webservice.model.ContentsDBContent;
import canss.webservice.model.EventDescription;
import canss.webservice.model.Feed;
import canss.webservice.model.SCPContentWrap;
import canss.webservice.controls.FeedControl;
import canss.webservice.controls.LinkageControl;
import canss.webservice.controls.SimplifiedContentControl;

@WebService
public class CANSSAPI
{

	@Control
	private ContentControl contentControl;
	@Control
	private ContentDescControl contentdesccontrol;
	@Control
	private PersonControl personcontrol;
	@Control
	private ContentsChannelHoldsControl contentsChannelHoldsControl;

	

	@WebMethod
	public String getAgreedContents(String _key, String _pid)
	{
		if (!checkTRKey(_key, _pid))
			return XML_INFORM_WRONGKEY;
		try
		{
			String _filter = null;
			ContentsChannelHolds[] contentholds = contentsChannelHoldsControl.getContentsChannelHoldsByPID(_pid);
			if(contentholds!=null)
			{
				for(ContentsChannelHolds contenthold : contentholds)
				{
					_filter = contenthold.getFILTER_RULE();
					break;
				}
			}
			
			if(!basic.isEmpty(_filter))
			{
				ContentsDBContent[] ret = contentControl.getAgreedContentsByFilter(_filter);
				if (ret != null)
				{
					return ContentsDBContent.toXML(false, ret);
				}else
					return null;
			}
		} catch (MalformedURLException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLExceptionWrapper e)
		{
			e.printStackTrace();
		}
		return XML_INFORM_BASIC;
	}
	
	@WebMethod
	public String getAgreedContentsFromWhen(String _key, String _pid, long _when)
	{
		if (!checkTRKey(_key, _pid))
			return XML_INFORM_WRONGKEY;
		try
		{
			String _filter = null;
			ContentsChannelHolds[] contentholds = contentsChannelHoldsControl.getContentsChannelHoldsByPID(_pid);
			if(contentholds!=null)
			{
				for(ContentsChannelHolds contenthold : contentholds)
				{
					_filter = contenthold.getFILTER_RULE();
					break;
				}
			}
			
			if(!basic.isEmpty(_filter))
			{
				ContentsDBContent[] ret = contentControl.getAgreedContentsByFilterFrom(_filter, _when);
				if (ret != null)
				{
					return ContentsDBContent.toXML(false, ret);
				}else
					return null;
			}
		} catch (MalformedURLException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLExceptionWrapper e)
		{
			e.printStackTrace();
		}
		return XML_INFORM_BASIC;
	}
	

	@WebMethod
	public String[] getEntireFeeds(String _key, String _pid)
	{
		if (!checkTRKey(_key, _pid))
		{
			String[] retstr = new String[1];
			retstr[0] = XML_INFORM_WRONGKEY;
			return retstr;
		}
		try
		{
			Feed[] feedlist = feedControl.getFeedByMultiple(_pid, "100");
			if (feedlist != null)
			{
				String[] ret = new String[feedlist.length];
				for (int i = 0; i < ret.length; i++)
					ret[i] = new String(feedlist[i].getFEEDURI());
				return ret;
			}else
				return null;
		} catch (SQLExceptionWrapper e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		{
			String[] retstr = new String[1];
			retstr[0] = XML_INFORM_BASIC;
			return retstr;
		}
	}

	@WebMethod
	public String addNewFeed(String _key, String _pid, String _feeduri)
	{
		if (!checkTRKey(_key, _pid))
			return XML_INFORM_WRONGKEY;
		if (_feeduri != null)
		{
			try
			{
				Feed[] feedlist = feedControl.getFeedByMultiple(_pid, "100");
				if (feedlist != null)
				{
					boolean ret = false;
					for (Feed feed : feedlist)
						ret |= _feeduri.equalsIgnoreCase(feed.getFEEDURI());
					if (ret)
						return feedControl.createFeedUri(_pid, "100", _feeduri).toString();
				}else
					return feedControl.createFeedUri(_pid, "100", _feeduri).toString();
			} catch (SQLExceptionWrapper e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return XML_INFORM_BASIC;
	}

	@WebMethod
	public String deleteFeed(String _key, String _pid, String _feeduri)
	{
		if (!checkTRKey(_key, _pid))
			return XML_INFORM_WRONGKEY;
		if (_feeduri != null)
		{
			try
			{
				Feed[] feedlist = feedControl.getFeedByMultiple(_pid, "100");
				if (feedlist != null)
				{
					boolean ret = false;
					for (Feed feed : feedlist)
						ret |= _feeduri.equalsIgnoreCase(feed.getFEEDURI());
					if (ret)
						return feedControl.deleteFeed(_pid, "100", _feeduri).toString();
				}
			} catch (SQLExceptionWrapper e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return XML_INFORM_BASIC;
	}

	@WebMethod
	public String getContentStatusByContId(String _key, String _pid, String[] _ContId)
	{
		if (!checkTRKey(_key, _pid))
			return XML_INFORM_WRONGKEY;
		try
		{
			StringBuffer strbuf = new StringBuffer();
			strbuf.append(basic.getXMLStart());
			if(_ContId != null)
			{
				strbuf.append("<canssContent:mediaGroup>");
				for(String iter_ContId : _ContId)
				{
					String[] retlinkage = linkageControl.getLinkageByCONTID(_pid, iter_ContId);
					if(retlinkage!=null)
					{
						for(String iter_cid : retlinkage)
						{
							ContentDesc retdesc = contentdesccontrol.getContentDescription(iter_cid);
							if(retdesc!=null)
							{
								Integer retstatus = retdesc.getCANSSCONTENTDESCRIPTION_STATUS();
								if(retstatus!=null)
								{
									EventDescription oneEventDesc = eventDescriptionControl.getEventDescByEventID(retstatus);
									if(oneEventDesc!=null)
									{
										strbuf.append("<canssContent:media>");
										
										strbuf.append("<ContId>");
										strbuf.append(""+iter_ContId);
										strbuf.append("</ContId>");
										strbuf.append("<canssContentDescription:contentId>");
										strbuf.append(""+iter_cid);
										strbuf.append("</canssContentDescription:contentId>");
										strbuf.append("<canssContentDescription:status>");
										strbuf.append(""+retstatus);
										strbuf.append("</canssContentDescription:status>");
										strbuf.append(oneEventDesc.toString());
	
										strbuf.append("</canssContent:media>");
									}
								}
							}
						}
					}
				}
				strbuf.append("</canssContent:mediaGroup>");
			}
			strbuf.append(basic.getXMLEnd());
			
			return strbuf.toString();
		} catch (SQLExceptionWrapper e)
		{
			e.printStackTrace();
		}
		
		return XML_INFORM_BASIC;
	}
	
	@WebMethod
	public String setContentStatusByContId(String _key, String _pid, String _ContId, Integer _status)
	{
		if (!checkTRKey(_key, _pid))
			return XML_INFORM_WRONGKEY;
		try
		{
			String[] retlinkage = linkageControl.getLinkageByCONTID(_pid, _ContId);
			if(retlinkage!=null && retlinkage.length>0)
			{
				//from	277	277	299	300	300	310
				//to	300	330	330	310	330	300
				String from_to = "277300,277330,299330,300310,300330,310300";
				int from = contentdesccontrol.getContentStatusByCID(retlinkage[0]);
				int to = _status;
				boolean check = from_to.indexOf(from+""+to)>=0;
				if(check)
				{
					contentdesccontrol.setContentStatus(retlinkage[0], _status);
					return XML_INFORM_SUCCESS;
				}else
				{
					return XML_INFORM_START + "Not Allowed to Change" + XML_INFORM_END;
				}
			}
		} catch (SQLExceptionWrapper e)
		{
			e.printStackTrace();
		}
		
		return XML_INFORM_BASIC;
	}
	
	@WebMethod
	public String updateContentDetail(String _key, String _pid, SCPContentWrap[] _list)
	{
		if (!checkTRKey(_key, _pid))
			return XML_INFORM_WRONGKEY;
		
	
		StringBuffer outbuf = new StringBuffer();
		if(_list!=null)
		{
			for(SCPContentWrap scpcontentwrap : _list)
			{
				try
				{
					String[] retlinkage = linkageControl.getLinkageByCONTID(_pid, scpcontentwrap.getCONTID());
					if(retlinkage!=null && retlinkage.length>0)
					{
						int ret = simplifiedContentControl.updateSimplifiedContentsByCID(retlinkage[0], scpcontentwrap.createSCPContentObj());
						if(ret>0)
						{
							outbuf.append(XML_INFORMGROUP_START);
							outbuf.append(XML_INFORM_START);
							outbuf.append("<ContId>" + scpcontentwrap.getCONTID() + "</ContId>");
							outbuf.append(XML_INFORM_END);
							outbuf.append(XML_INFORM_SUCCESS);
							outbuf.append(XML_INFORMGROUP_END);
							continue;
						}
					}
				} catch (SQLExceptionWrapper e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
					break;
				}
				outbuf.append(XML_INFORMGROUP_START);
				outbuf.append(XML_INFORM_START);
				outbuf.append("<ContId>" + scpcontentwrap.getCONTID() + "</ContId>");
				outbuf.append(XML_INFORM_END);
				outbuf.append(XML_INFORM_BASIC);
				outbuf.append(XML_INFORMGROUP_END);
			}
			return outbuf.toString();
		}
		return XML_INFORM_BASIC;
	}
	
	@WebMethod
	public String getAddressOfFeedRuleEditor(String _key, String _pid, String _feeduri)
	{
		if (!checkTRKey(_key, _pid))
			return XML_INFORM_WRONGKEY;
		if (_feeduri != null)
		{
			try
			{
				Feed[] feedlist = feedControl.getFeedByMultiple(_pid, "100");
				if (feedlist != null)
				{
					boolean ret = false;
					for (Feed feed : feedlist)
						ret |= _feeduri.equalsIgnoreCase(feed.getFEEDURI());
					if (ret)
						return "http://canss.net/CANSSWebService/BoundRuleEdit?param=" + DBStringEncoder.Server2DB("_feed=" + _feeduri + "&_cpid=" + _pid);
				}
			} catch (SQLExceptionWrapper e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return XML_INFORM_BASIC;
	}
	@WebMethod
	public String getAddressOfChannelRuleEditor(String _key, String _pid)
	{
		if (!checkTRKey(_key, _pid))
			return XML_INFORM_WRONGKEY;
		try
		{
			Channel[] channellist = channelControl.getChannelByPID(_pid);
			if(channellist!=null && channellist.length>0)
			{
				Integer _index = channellist[0].getINDEX_2();
				if(_index!=null)
					return "http://canss.net/CANSSWebService/BoundRevRuleEdit?param=" + DBStringEncoder.Server2DB("_3pid=" + _pid + "&_chid=" + _index);
			}
		} catch (SQLExceptionWrapper e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return XML_INFORM_BASIC;
	}


	@WebMethod
	public String getAddressOfContentsPort(String _key)
	{
		try
		{
			String _pid = personcontrol.getPersonIDByKey(_key);
			if (!basic.isEmpty(_pid))
				return "http://portal.canss.net/svtContentsPort?_channelname=channel1&amp;_key=" + _key;
			return XML_INFORM_WRONGKEY;
		} catch (SQLExceptionWrapper e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RuntimeException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return XML_INFORM_BASIC;
	}

	@WebMethod
	public String getEUsContentStatus(String _key, String _pid)
	{
		if (!checkTRKey(_key, _pid))
			return XML_INFORM_WRONGKEY;

		try
		{
			ContentDesc[] contentdesc = contentdesccontrol.getContentDescriptionByPID(_pid);
			if (contentdesc != null)
			{
				Hashtable<String, ContentsDBContent> contentlist_hash = new Hashtable<String, ContentsDBContent>();
				{
					String query = "";
					boolean isfirst = true;
					for (ContentDesc desc : contentdesc)
					{
						if (isfirst)
							isfirst = false;
						else
							query += " OR ";
						query += "tblCID_cid=" + "\"" + desc.getTBLCID_CID() + "\"";
					}

					ContentsDBContent[] retcontentlist = contentControl.getContentsByFilter(query);

					if (retcontentlist != null)
						for (ContentsDBContent content : retcontentlist)
							contentlist_hash.put(content.getCANSSCONTENTDESCRIPTION_CONTENTID(), content);

				}

				LinkedList<ContentsDBContent> list = new LinkedList<ContentsDBContent>();
				for (ContentDesc desc : contentdesc)
					list.add(contentlist_hash.get(desc.getTBLCID_CID()));

				ContentsDBContent[] finallist = new ContentsDBContent[list.size()];
				for (int i = 0; i < finallist.length; i++)
					finallist[i] = list.remove();

				return ContentsDBContent.toXML(false, finallist);
			}else
				return null;
		} catch (SQLExceptionWrapper e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return XML_INFORM_BASIC;
	}

	private final boolean checkTRKey(String _key, String _pid)
	{
		try
		{
			String pid = personcontrol.getPersonIDByKey(_key);
			if (pid != null)
				return pid.equalsIgnoreCase(_pid);
		} catch (SQLExceptionWrapper e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RuntimeException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	@SuppressWarnings("unused")	private static final String XML_INFORMGROUP_START = "<informgroup>";
	@SuppressWarnings("unused")	private static final String XML_INFORMGROUP_END = "</informgroup>";
	@SuppressWarnings("unused")	private static final String XML_INFORM_START = "<inform>";
	@SuppressWarnings("unused")	private static final String XML_INFORM_END = "</inform>";
	@SuppressWarnings("unused")	private static final String XML_INFORM_WRONGKEY = "<inform>Wrong key value</inform>";
	@SuppressWarnings("unused")	private static final String XML_INFORM_BASIC = "<inform>Error</inform>";
	@SuppressWarnings("unused")	private static final String XML_INFORM_SUCCESS = "<inform>Success</inform>";
	@Control
	private FeedControl feedControl;
	@Control
	private ChannelControl channelControl;
	@Control
	private LinkageControl linkageControl;
	@Control
	private EventDescriptionControl eventDescriptionControl;
	@Control
	private SimplifiedContentControl simplifiedContentControl;
}